#include "BaseType.h"
#include "Tracer.h"
using namespace std;
using namespace libemb;

/**
 * 备忘录模式：
 * 1.在不破坏封装性的前提下捕获一个类的状态，以便在需要的时候可以从该状态恢复
 * 2.捕获的状态保存在备忘录中
 * 适用场景：
 * 1.在一个编辑器中保存历史状态，这样便可以实现撤销功能。
 * 2.在执行任务之前保存状态，以便撤销任务后能恢复到当前状态。
 **/

//编辑状态
struct State{
    int m_linenum{-1};
    int m_command{-1};
};

//备忘录
class Memento{
public:
    Memento(State& state):
    m_state(state)
    {
    }
private:
    /* 只提供给Editor访问 */
    State getState()
    {
        return m_state;
    }
private:
    friend class Editor;
    State m_state;
};

//编辑器
class Editor{
DECL_CLASSNAME(Editor)
public:
    std::shared_ptr<Memento> createMemento()
    {
        return std::make_shared<Memento>(m_state);
    }
    void restoreMemonto(std::shared_ptr<Memento> mem)
    {
        m_state = mem->getState();
    }
    void edit(int line, int command)
    {
        m_state.m_linenum = line;
        m_state.m_command = command;
    }
    void showState()
    {
        TRACE_INFO_CLASS("current state--> linenum:%d, command:%d",m_state.m_linenum,m_state.m_command);
    }
private:
    State m_state;
};


int main()
{
    Tracer::getInstance().setLevel(TRACE_LEVEL_DBG);
	Tracer::getInstance().addSink(std::make_shared<STDSink>()).start();

    Editor editor;
    editor.edit(10,1);
    auto mem01 = editor.createMemento();//创建一个备忘录作为还原点

    editor.edit(20,2);
    auto mem02 = editor.createMemento();//创建一个备忘录作为还原点

    //恢复备忘录01
    editor.restoreMemonto(mem01);
    editor.showState();

    //恢复备忘录02
    editor.restoreMemonto(mem02);
    editor.showState();
    return RC_OK;
}